#ifndef __CUST_SX127X_H__
#define __CUST_SX127X_H__

#define __SX1276_7_8__
//#define  __SX1272__
#include "sx127xRegs_FSK.h"
#include "sx127xRegs_LoRa.h"

#define __SX1272_CHIP_VERSION__	(0x22)
#define __SX1276_CHIP_VERSION__	(0x12)

#define __SX127X_TX_ACK_OK__	(1)
#define __SX127X_TX_ACK_FAIL__	(0)
/*!
 * Radio wake-up time from sleep
 */
#define RADIO_WAKEUP_TIME                           2 // [ms]
#ifdef __SX1276_7_8__
#define RF_MID_BAND_THRESH                          525000000
#endif
/*!
 * Sync word for Private LoRa networks
 */
#define LORA_MAC_PRIVATE_SYNCWORD                   0x12

/*!
 * Sync word for Public LoRa networks
 */
#define LORA_MAC_PUBLIC_SYNCWORD                    0x34

typedef union
{
	uint32_t 	UID[3];
	uint8_t 	Data[12];
}ID_Union;
/*!
 * Radio LoRa modem parameters
 */
typedef struct
{
	ID_Union 	uID;
	int32_t		LastReqError;
    uint32_t	RFHFreq;
    uint32_t	RFLFreq;
    uint32_t	CurFreq;
    uint32_t	TxTimeout;
    uint16_t	PreambleLen;//Length in symbols (the hardware adds 4 more symbols)
    uint16_t	RxTimeout;
    uint8_t 	IDLen;
    uint8_t		PayloadMaxLen;
    uint8_t		Bandwidth;
    uint8_t		Datarate;
    uint8_t		Coderate;
    uint8_t		RFHPower;
    uint8_t		RFLPower;
    uint8_t 	PABoostSW;//Boost output 0: no use, 0x01: in RFL, 0x02: in RFH, 0x03: all use
    uint8_t		TxContinuous;
    uint8_t		ImplicitHeader;
    uint8_t		ImplicitPayloadLen;
    uint8_t		CrcOn;
    uint8_t		HopPeriod; //param [IN] hopPeriod    Number of symbols between each hop LoRa: Number of symbols
    uint8_t		IqInverted; // iqInverted   Inverts IQ signals (LoRa only) LoRa: [0: not inverted, 1: inverted]
    uint8_t		PublicNetwork;
    uint8_t		SyncCode;
    uint8_t		AGCAuto;
    uint8_t 	RFState;
    uint8_t		ChipVersion;
    uint8_t		NewConfig;

}RadioLoRaSettings_t;

/*!
 * Radio LoRa packet handler state
 */
typedef struct
{
	int16_t RssiValue;
    int8_t SnrValue;
    uint8_t Size;
}RadioLoRaPacketHandler_t;



/*!
 * Radio hardware and global parameters
 */

/*!
 * Hardware IO IRQ callback function definition
 */
typedef void ( DioIrqHandler )( void );

/*!
 * SX127x definitions
 */
#define XTAL_FREQ                                   32000000
#define FREQ_STEP                                   61.03515625
#define FREQ_STEP_8                                 15625 /* FREQ_STEP<<8 */

/* Freq = channel * FREQ_STEP */
#define SX_CHANNEL_TO_FREQ( channel, freq )                                                         \
    do                                                                                              \
    {                                                                                               \
        uint32_t initialChanInt, initialChanFrac;                                                   \
        initialChanInt = channel  >> 8;                                                             \
        initialChanFrac = channel - ( initialChanInt << 8 );                                        \
        freq = initialChanInt * FREQ_STEP_8 + ( ( initialChanFrac * FREQ_STEP_8 + ( 128 ) ) >> 8 ); \
    }while( 0 )

/* channel = Freq / FREQ_STEP */
#define SX_FREQ_TO_CHANNEL( channel, freq )                                                                       \
    do                                                                                                            \
    {                                                                                                             \
        uint32_t initialFreqInt, initialFreqFrac;                                                                 \
        initialFreqInt = freq / FREQ_STEP_8;                                                                      \
        initialFreqFrac = freq - ( initialFreqInt * FREQ_STEP_8 );                                                \
        channel = ( initialFreqInt << 8 ) + ( ( ( initialFreqFrac << 8 ) + ( FREQ_STEP_8 / 2 ) ) / FREQ_STEP_8 ); \
    }while( 0 )

#define RX_BUFFER_SIZE                              256

typedef struct
{
	Timer_t AckTimer;
    RadioLoRaSettings_t      *Setting;
    uint32_t LastSec;
    uint32_t LastMsec;
    uint8_t TxBuf[257];
    uint8_t RxBuf[257];
    uint8_t AckBuf[257];
    uint8_t IsRepeat;
    uint8_t PackID;
    uint8_t RxLen;
    uint8_t XferLen;
    uint8_t CalCnt;
    uint8_t AppTaskID;
    uint8_t State;
    uint8_t IsSX1272;
    uint8_t ContinueRx;
    uint8_t AutoAck;
    uint8_t AckCheckLen;
    uint8_t ReSendCnt;
}SX127X_CtrlStruct;

enum
{
	SX127X_BOOST_RFL = 0x01,
	SX127X_BOOST_RFH = 0x02,
    RF_STATE_IDLE = 0,   //!< The radio is idle
    RF_STATE_RX_RUNNING, //!< The radio is in reception state
    RF_STATE_TX_RUNNING, //!< The radio is in transmission state
    RF_STATE_CAD,        //!< The radio is doing channel activity detection
	SX127X_LORA_BW_125K = 0,
	SX127X_LORA_BW_250K,
	SX127X_LORA_BW_500K,
	SX127X_LORA_CODERATE_5 = 0,
	SX127X_LORA_CODERATE_6,
	SX127X_LORA_CODERATE_7,
	SX127X_LORA_CODERATE_8,

};
void SX127X_PrintReg(uint8_t SpiID, uint8_t Reg);
uint8_t SX127X_ReadReg(uint8_t SpiID, uint8_t Reg, int32_t *Error);
int32_t SX127X_WriteReg(uint8_t SpiID, uint8_t Reg, uint8_t Value);
int32_t SX127X_WriteAndVerifyReg(uint8_t SpiID, uint8_t Reg, uint8_t Value);
int32_t SX127X_ModifyReg(uint8_t SpiID, uint8_t Reg, uint8_t Mask, uint8_t Value);
int32_t SX127X_ReadfifoSync(uint8_t SpiID, uint8_t *Buf, uint8_t DataLen);
int32_t SX127X_WritefifoSync(uint8_t SpiID, uint8_t *Buf, uint8_t DataLen);
int32_t SX127X_ReadfifoASync(uint8_t SpiID, uint8_t *Buf, uint8_t DataLen);
int32_t SX127X_WritefifoASync(uint8_t SpiID, uint8_t *Buf, uint8_t DataLen);

/*!
 * \brief Sets the SX127X operating mode
 *
 * \param [IN] opMode New operating mode
 */
int32_t SX127X_SetOpMode( uint8_t SpiID, uint8_t opMode );
int32_t SX127X_SetOpModeWithoutCheck( uint8_t SpiID, uint8_t opMode );
int32_t SX127X_GetOpMode(uint8_t SpiID, uint8_t *opMode);
int32_t SX127X_CheckVersion(uint8_t SpiID, uint8_t Version);
int32_t SX127X_SetChannel( uint8_t SpiID, uint32_t Freq );
int32_t SX127X_ChipInit(uint8_t SpiID);
int32_t SX127X_SetModem(uint8_t SpiID, uint8_t IsLoRa);
int32_t SX127X_ReadAndClearIrq(uint8_t SpiID, uint8_t *IrqFlag);
int32_t SX127X_ClearIrq(uint8_t SpiID, uint8_t IrqFlag);
int32_t SX127X_EnableIrq(uint8_t SpiID, uint8_t IrqFlag);
int32_t SX127X_DisableIrq(uint8_t SpiID, uint8_t IrqFlag);
int32_t SX127X_StartCal(uint8_t SpiID);
int32_t SX127X_CheckCalDone(uint8_t SpiID);
int32_t SX127X_SetTxPower(uint8_t SpiID, uint8_t ChipID, uint8_t Power, uint8_t PaSelect);
int32_t SX127X_SetConfig(uint8_t SpiID, RadioLoRaSettings_t *Setting);
int32_t SX127X_SetTx(uint8_t SpiID);
int32_t SX127X_SetRx(uint8_t SpiID);
int32_t SX127X_SetCAD(uint8_t SpiID);
int32_t SX127X_RxGetDataAsync(uint8_t SpiID, uint8_t *Buf, uint8_t *RxLen);
void SX127X_Reset(void);
#endif
